package com.ruoyi.api.controller.user;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.qiniu.util.StringUtils;
import com.ruoyi.api.annotation.IgnoreAuth;
import com.ruoyi.api.bo.UserInfo;
import com.ruoyi.api.bo.WxUserProfile;
import com.ruoyi.api.service.ApiTokenService;
import com.ruoyi.api.utils.ApiUserUtils;
import com.ruoyi.api.utils.SmsUtils;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.deal.domain.HyDealOrder;
import com.ruoyi.system.domain.HyUser;
import com.ruoyi.system.service.IHyUserService;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * API登录验证
 *
 * @author lixin
 * @date 2021-06-03 18:38
 */
@Slf4j
@RestController
@RequestMapping("/api")
public class ApiLoginController {

	@Autowired
	private IHyUserService userService;

	@Autowired
	private ApiTokenService tokenService;

	@Autowired
	private ApiUserUtils apiUserUtils;

	@Autowired
	private SmsUtils smsUtils;

	/**
	 * 用户注册
	 *
	 * @return 结果
	 */
	@IgnoreAuth
	@PostMapping("/register")
	public AjaxResult register(@RequestBody HyUser hyUser) {

		if (StrUtil.isEmpty(hyUser.getPhonenumber())) {
			return AjaxResult.error("手机号不能为空");
		}
		if (StrUtil.isEmpty(hyUser.getPassword())) {
			return AjaxResult.error("密码不能为空");
		}
		if (StrUtil.isEmpty(hyUser.getCode())) {
			return AjaxResult.error("验证码不能为空");
		}
		// 注册前查询是否有重复号码
		HyUser user = userService.queryByPhoneNumber(hyUser.getPhonenumber());
		if (ObjectUtil.isNotNull(user)) {
			return AjaxResult.error("该手机号已存在，请登录");
		}
		//用户注册
		if(userService.register(hyUser.getPhonenumber(), hyUser.getPassword(), hyUser.getCode())) {
			return AjaxResult.success("注册成功，请登录");
		}
		return AjaxResult.error("注册失败");

	}

	/**
	 * 账户密码登录
	 *
	 * @return 结果
	 */
	@IgnoreAuth
	@PostMapping("/login")
	public AjaxResult login(@RequestBody HyUser hyUser) {

		if (StrUtil.isEmpty(hyUser.getPhonenumber())) {
			return AjaxResult.error("手机号不能为空");
		}
		if (StrUtil.isEmpty(hyUser.getPassword())) {
			return AjaxResult.error("密码不能为空");
		}
		//用户登录
		HyUser user = userService.login(hyUser.getPhonenumber(), hyUser.getPassword());

		String token = tokenService.createToken(user);

		if (StringUtils.isNullOrEmpty(token)) {
			return AjaxResult.error("登录失败");
		}

		Map<String, Object> resultObj = new HashMap<String, Object>();
		resultObj.put("token", token);
		resultObj.put("userInfo", user);

		return AjaxResult.success(resultObj);
	}

	/**
	 * 验证码登录
	 *
	 * @return 结果
	 */
	@IgnoreAuth
	@PostMapping("/loginByVerificationCode")
	public AjaxResult loginByVerificationCode(@RequestBody HyUser hyUser) {

		//用户登录
		HyUser user = userService.loginByVerificationCode(hyUser.getPhonenumber(), hyUser.getCode());

		String token = tokenService.createToken(user);

		if (StringUtils.isNullOrEmpty(token)) {
			return AjaxResult.error("登录失败");
		}

		Map<String, Object> resultObj = new HashMap<String, Object>();
		resultObj.put("token", token);
		resultObj.put("userInfo", user);

		return AjaxResult.success(resultObj);
	}

	/**
	 * 发送验证码
	 * @param params
	 * @return
	 */
	@IgnoreAuth
	@PostMapping("/sendCode")
	public AjaxResult sendCode(@RequestBody Map<String, String> params) {
		// 如果类型不是注册需要查询数据库有没有用户
		if(!StrUtil.equals(params.get("type"), "register")) {
			HyUser user = userService.queryByPhoneNumber(params.get("phonenumber"));
			if(ObjectUtil.isNull(user)) {
				return AjaxResult.error("号码不存在，请先注册");
			}
		}
		smsUtils.sendVerificationCode(params.get("phonenumber"), RandomUtil.randomNumbers(6));
		return AjaxResult.success();
	}

	/**
	 * 微信小程序-微信授权登录
	 * @param wxUserProfile
	 * @return
	 */
	@IgnoreAuth
	@PostMapping("/loginByWx")
	public AjaxResult loginByWx(@RequestBody WxUserProfile wxUserProfile) {

		String code = wxUserProfile.getCode();
		if (ObjectUtil.isNull(wxUserProfile)) {
			return AjaxResult.error("登录失败");
		}

		UserInfo userInfo = wxUserProfile.getUserInfo();

		//获取openid
		String requestUrl = apiUserUtils.getWebAccess(code);
		log.info("》》》组合token为：" + requestUrl);

		// {"session_key":"ynT3dgO2FqRejXwjokwOgg==","openid":"oXDJI4-Vt8YdbV-bFTw8wzCycrAg"}
		JSONObject sessionData = JSONUtil.parseObj(HttpUtil.get(requestUrl));


		if (ObjectUtil.isNull(sessionData) || StringUtils.isNullOrEmpty(sessionData.getStr("openid"))) {
			return AjaxResult.error("登录失败");
		}

		//验证用户信息完整性
		String sha1 = SecureUtil.sha1(wxUserProfile.getRawData() + sessionData.getStr("session_key"));

		if (!StrUtil.equals(wxUserProfile.getSignature(), sha1)) {
			return AjaxResult.error("登录失败");
		}

		HyUser user = userService.queryByOpenId(sessionData.getStr("openid"));

		Date nowTime = DateUtil.date(System.currentTimeMillis());
		if (ObjectUtil.isNull(user)) {
			user = new HyUser();
			user.setUserName("微信小程序用户" + RandomUtil.randomString(12));
			user.setPassword(sessionData.getStr("openid"));
			user.setLoginTime(nowTime);
			user.setLoginIp(ServletUtils.getClientIP());
			user.setWxOpenid(sessionData.getStr("openid"));
			user.setAvatar(userInfo.getAvatarUrl());
			//性别 0：未知、1：男、2：女
			user.setSex(userInfo.getGender() == 1 ? "0" : (userInfo.getGender() == 2 ? "1" : "2"));
			user.setNickName(userInfo.getNickName());
			userService.save(user);
		} else {
			user.setAvatar(userInfo.getAvatarUrl());
			user.setSex(userInfo.getGender() == 1 ? "0" : (userInfo.getGender() == 2 ? "1" : "2"));
			user.setNickName(userInfo.getNickName());
			user.setLoginTime(nowTime);
			user.setLoginIp(ServletUtils.getClientIP());
			userService.updateById(user);
		}

		String token = tokenService.createToken(user);

		if (null == userInfo || StringUtils.isNullOrEmpty(token)) {
			return AjaxResult.error("登录失败");
		}

		Map<String, Object> resultObj = new HashMap<String, Object>();
		resultObj.put("token", token);
		resultObj.put("userInfo", user);

		return AjaxResult.success(resultObj);
	}

	/**
	 * APP-微信授权登录
	 * @param userInfo
	 * @return
	 */
	@IgnoreAuth
	@PostMapping("/appLoginByWx")
	public AjaxResult appLoginByWx(@RequestBody UserInfo userInfo) {

		if (ObjectUtil.isNull(userInfo)) {
			return AjaxResult.error("登录失败");
		}

		//获取openid
		String openId = userInfo.getOpenId();

		if (StringUtils.isNullOrEmpty(openId)) {
			return AjaxResult.error("登录失败");
		}

		HyUser user = userService.queryByOpenId(openId);

		Date nowTime = DateUtil.date(System.currentTimeMillis());
		if (ObjectUtil.isNull(user)) {
			user = new HyUser();
			user.setUserName("微信用户" + RandomUtil.randomString(12));
			user.setPassword(openId);
			user.setLoginTime(nowTime);
			user.setLoginIp(ServletUtils.getClientIP());
			user.setWxOpenid(openId);
			user.setAvatar(userInfo.getAvatarUrl());
			//性别 0：未知、1：男、2：女
			user.setSex(userInfo.getGender() == 1 ? "0" : (userInfo.getGender() == 2 ? "1" : "2"));
			user.setNickName(userInfo.getNickName());
			userService.save(user);
		} else {
			user.setAvatar(userInfo.getAvatarUrl());
			user.setSex(userInfo.getGender() == 1 ? "0" : (userInfo.getGender() == 2 ? "1" : "2"));
			user.setNickName(userInfo.getNickName());
			user.setLoginTime(nowTime);
			user.setLoginIp(ServletUtils.getClientIP());
			userService.updateById(user);
		}

		String token = tokenService.createToken(user);

		if (StringUtils.isNullOrEmpty(token)) {
			return AjaxResult.error("登录失败");
		}

		Map<String, Object> resultObj = new HashMap<String, Object>();
		resultObj.put("token", token);
		resultObj.put("userInfo", user);

		return AjaxResult.success(resultObj);
	}

	/**
	 * APP-QQ授权登录
	 * @param userInfo
	 * @return
	 */
	@IgnoreAuth
	@PostMapping("/appLoginByQQ")
	public AjaxResult appLoginByQQ(@RequestBody UserInfo userInfo) {

		if (ObjectUtil.isNull(userInfo)) {
			return AjaxResult.error("登录失败");
		}

		//获取openid
		String openId = userInfo.getOpenId();

		if (StringUtils.isNullOrEmpty(openId)) {
			return AjaxResult.error("登录失败");
		}

		HyUser user = userService.queryByOpenId(openId);

		Date nowTime = DateUtil.date(System.currentTimeMillis());
		if (ObjectUtil.isNull(user)) {
			user = new HyUser();
			user.setUserName("QQ用户" + RandomUtil.randomString(12));
			user.setPassword(openId);
			user.setLoginTime(nowTime);
			user.setLoginIp(ServletUtils.getClientIP());
			user.setWxOpenid(openId);
			user.setAvatar(userInfo.getAvatarUrl());
			//性别 0：未知、1：男、2：女
			user.setSex(userInfo.getGender() == 1 ? "0" : (userInfo.getGender() == 2 ? "1" : "2"));
			user.setNickName(userInfo.getNickName());
			userService.save(user);
		} else {
			user.setAvatar(userInfo.getAvatarUrl());
			user.setSex(userInfo.getGender() == 1 ? "0" : (userInfo.getGender() == 2 ? "1" : "2"));
			user.setNickName(userInfo.getNickName());
			user.setLoginTime(nowTime);
			user.setLoginIp(ServletUtils.getClientIP());
			userService.updateById(user);
		}

		String token = tokenService.createToken(user);

		if (StringUtils.isNullOrEmpty(token)) {
			return AjaxResult.error("登录失败");
		}

		Map<String, Object> resultObj = new HashMap<String, Object>();
		resultObj.put("token", token);
		resultObj.put("userInfo", user);

		return AjaxResult.success(resultObj);
	}

}
